﻿using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using CoreApp.DBAccess;
using CoreApp.Utility;
using CoreApp.WebApi.Core;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;

namespace CoreApp.WebApi.Controllers
{
    [Route("api/Auth/[action]")]
    [ApiController]
    public class AuthController : ControllerBase
    {
        private readonly IUserRepository userRepository;
        public AuthController(IUserRepository _userRepository)
        {
            userRepository = _userRepository;
        }

        /**
         * 获取token
         * 在api/controller/action加上Authorize权限校验特性，客户端调用如果没有通过权限校验，则http返回状态码为401
         * 客户端调用接口的方式如下：
         * 1.调用api/Auth接口获取到token
         * 2.调用需要授权接口时，在请求的Header中添加参数 Authorization: Bearer token值
         * 注意：Bearer后面有空格，空格后面是第一步中接口获取的token值
         * */
        [AllowAnonymous]
        [HttpPost]
        public async Task<IActionResult> GetToken([FromForm]string username, [FromForm]string userpwd)
        {
            if (string.IsNullOrWhiteSpace(username) || string.IsNullOrWhiteSpace(userpwd))
                return BadRequest(new { code = "failed", msg = "username or userpwd is empty" });

            var MD5Pwd = Md5Helper.MD5Hash(userpwd);//md5加密
            var userInfo = await userRepository.QueryUser(username, MD5Pwd);
            if (userInfo == null)
                return BadRequest(new { code = "failed", msg = "user is not exist" });

            //添加声明
            var claims = new[]
            {
                //编号（JWT ID）
                new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
                //签发时间（Issued At）
                new Claim(JwtRegisteredClaimNames.Iat, $"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}"),
                //生效时间（Not Before）
                new Claim(JwtRegisteredClaimNames.Nbf,$"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}") ,
                //过期时间（expiration time）
                new Claim (JwtRegisteredClaimNames.Exp,$"{new DateTimeOffset(DateTime.Now.AddMinutes(30)).ToUnixTimeSeconds()}"),
                //储存用户name
                new Claim(ClaimTypes.Name, username)
            };
            //签名需要的密钥
            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Const.SecurityKey));
            var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
            var token = new JwtSecurityToken(
                    issuer: Const.Domain,//签发人
                    audience: Const.Domain,//受众
                    claims: claims,
                    expires: DateTime.Now.AddMinutes(30),
                    signingCredentials: creds
            );
            var tokenstr = new JwtSecurityTokenHandler().WriteToken(token);

            return Ok(new
            {
                code = "success",
                token = tokenstr
            });
        }
    }
}